#include "splitteredlayout.h"
#include "panelsplitter.h"
#include "../PanelMover/panelmover.h"
#include "../SlidingWindow/slidingwindow.h"
#include "../Favorites/favoritespanel.h"
#include "centralwidgetcontainer.h"
#include "../TabButtonsPanel/tabbuttonspanel.h"
#include <QCursor>
#include <QHBoxLayout>
#include <QPushButton>
#include <QEvent>

using namespace ExecTerminalImplNS;

const int MAIN_LAYOUT_MARGIN = 0;
const int MAIN_LAYOUT_SPACING = 0;
const int INIT_FAVORITES_WIDTH = 200;
const int INIT_TABBUTTONS_PANEL_HEIGHT = 300;

SplitteredLayout::SplitteredLayout(QWidget * parent): QObject(parent),
theParentWidget(parent),
theMainLayout(0),
thePanelSplitter(0),
theVerticalSplitter(0),
theLeftPanelSlider(0),
theFavoritesPanel(0),
theLeftPanelMover(0),
theCentralWidgetCont(0)
{
    initMainWidgets();
}

SplitteredLayout::~SplitteredLayout()
{

}

void SplitteredLayout::initMainWidgets()
{
    theCentralWidgetCont = new CentralWidgetContainer(theParentWidget);
    theMainLayout = new QHBoxLayout();
    thePanelSplitter = new PanelSplitter(theParentWidget);
    thePanelSplitter->addWidget(theCentralWidgetCont);
    thePanelSplitter->installEventFilter(this);
    theLeftPanelSlider = new SlidingWindow(theParentWidget);
    theLeftPanelSlider->resize(INIT_FAVORITES_WIDTH, theLeftPanelSlider->height());

    theVerticalSplitter = new PanelSplitter(theLeftPanelSlider);
    theVerticalSplitter->setOrientation(Qt::Vertical);
    theFavoritesPanel = new FavoritesPanel(theVerticalSplitter);
    theVerticalSplitter->addWidget(theFavoritesPanel);
    theTabButtonsPanel = new TabButtonsPanel(theVerticalSplitter);
    theVerticalSplitter->addWidget(theTabButtonsPanel);
    theTabButtonsPanel->hide();

    theLeftPanelSlider->setSlideDirection(ExecTerminalImplNS::SlideToLeft);
    theLeftPanelSlider->setCentralWidget(theVerticalSplitter);
    connect(theLeftPanelSlider, SIGNAL(slidingFinished()), SLOT(horSlidingFinished()));

    theLeftPanelMover = new ExecTerminalImplNS::PanelMover(theParentWidget);
    theLeftPanelMover->setPosition(LEFT_POSITION);
    connect(theLeftPanelMover->hideButton(), SIGNAL(clicked()), SLOT(switchVisibility()));
    connect(theLeftPanelMover->moveButton(), SIGNAL(clicked()), SLOT(changeOrientation()));

    theMainLayout->setSpacing(MAIN_LAYOUT_SPACING);
    theMainLayout->setMargin(MAIN_LAYOUT_MARGIN);
    const bool leftLayout = true;
    doHorLayout(leftLayout);
}

QLayout * SplitteredLayout::layout()const
{
    return theMainLayout;
}

void SplitteredLayout::setVisibleToWidgets(bool vis)
{
    theLeftPanelMover->setVisible(vis);
    thePanelSplitter->setVisible(vis);
    theLeftPanelSlider->setVisible(vis);
}

void SplitteredLayout::changeOrientation()
{
    const bool isLeftPos = theLeftPanelMover->position() == ExecTerminalImplNS::LEFT_POSITION;
    const int oldXPos = theLeftPanelMover->x();
    if (isLeftPos)
    {
        theLeftPanelSlider->setSlideDirection(ExecTerminalImplNS::SlideToLeft);
    }
    else
    {
        theLeftPanelSlider->setSlideDirection(ExecTerminalImplNS::SlideToRight);
    }
    doHorLayout(isLeftPos);
    theCentralWidgetCont->switchPosition();
    if (!theSplitterSizes.isEmpty())
    {
        theSplitterSizes.swap(0, 1);
    }
    QCursor::setPos(QCursor::pos().x() + theLeftPanelMover->x() - oldXPos, QCursor::pos().y());
}

void SplitteredLayout::switchVisibility()
{
    const bool isLeftPos = theLeftPanelMover->position() == ExecTerminalImplNS::LEFT_POSITION;
    if (theLeftPanelSlider->isExpanded())
    {
       theSplitterSizes = thePanelSplitter->sizes();
       theLeftPanelSlider->setParent(theParentWidget);
       if (isLeftPos)
       {
           theLeftPanelSlider->move(theLeftPanelMover->x() + theLeftPanelMover->width(), theLeftPanelMover->y());
       }
       else
       {
           theLeftPanelSlider->move(theLeftPanelMover->x() - theLeftPanelSlider->width(), theLeftPanelMover->y());
       }
       theLeftPanelSlider->raise();
       theLeftPanelSlider->show();
    }
    else
    {
        if (isLeftPos)
        {
            theLeftPanelSlider->move(theLeftPanelMover->x() + theLeftPanelMover->width(), theLeftPanelMover->y());
        }
        else
        {
            theLeftPanelSlider->move(theLeftPanelMover->x() - theLeftPanelSlider->width(), theLeftPanelMover->y());
        }
    }
    theLeftPanelSlider->startSliding();

}

void SplitteredLayout::horSlidingFinished()
{
    const bool isLeftPos = theLeftPanelMover->position() == ExecTerminalImplNS::LEFT_POSITION;
    if (theLeftPanelSlider->isExpanded())
    {
        thePanelSplitter->insertWidget(isLeftPos ? 0 : 1 , theLeftPanelSlider);
        thePanelSplitter->setSizes(theSplitterSizes);
    }
}

void SplitteredLayout::doHorLayout(bool isPanelAtLeft)
{
    theParentWidget->setUpdatesEnabled(false);
    setVisibleToWidgets(false);
    theMainLayout->removeWidget(theLeftPanelMover); 
    theMainLayout->removeWidget(thePanelSplitter);
    if (theLeftPanelSlider->isExpanded())
    {
        theLeftPanelSlider->setParent(theParentWidget);
    }
    if (isPanelAtLeft)
    {
        theMainLayout->addWidget(theLeftPanelMover);
        theMainLayout->addWidget(thePanelSplitter);
        if (theLeftPanelSlider->isExpanded())
        {
            thePanelSplitter->insertWidget(0, theLeftPanelSlider);
        }
    }
    else
    {
        theMainLayout->addWidget(thePanelSplitter);
        theMainLayout->addWidget(theLeftPanelMover);
        if (theLeftPanelSlider->isExpanded())
        {
            thePanelSplitter->insertWidget(1, theLeftPanelSlider);
        }
    }
    setVisibleToWidgets(true);
    theMainLayout->activate();
    theParentWidget->setUpdatesEnabled(true);
}

QWidget * SplitteredLayout::centralWidget()const
{
    return theCentralWidgetCont->centralWidget();
}

bool SplitteredLayout::eventFilter(QObject *o, QEvent *e)
{
    if (e->type() == QEvent::Show && o == thePanelSplitter) 
    {
        QList<int> sizes = thePanelSplitter->sizes();
        static bool isFirstTime = true;
        if (isFirstTime)
        {
            sizes[0] -= INIT_FAVORITES_WIDTH;
            sizes[1] += sizes[0];
            sizes[0] = INIT_FAVORITES_WIDTH;
            thePanelSplitter->setSizes(sizes);

            sizes = theVerticalSplitter->sizes();
            sizes[1] -= INIT_TABBUTTONS_PANEL_HEIGHT;
            sizes[0] += sizes[0];
            sizes[1] = INIT_TABBUTTONS_PANEL_HEIGHT;
            theVerticalSplitter->setSizes(sizes);

            isFirstTime = false;
        }
    }
    return QObject::eventFilter(o, e);
}

void SplitteredLayout::setCentralWidget(QWidget * w)
{
    theCentralWidgetCont->setCentralWidget(w);
}

FavoritesPanel * SplitteredLayout::favoritesPanel()const
{
    return theFavoritesPanel;
}

